#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <libwebsockets.h>

#include "ws_server.h"
#include "http.h"

static volatile int exit_sig = 0;

void sighook(int sig)
{
    lwsl_notice("%d traped\n", sig);
    exit_sig = 1;
}

static const struct lws_protocol_vhost_options pvo_ops = {
    NULL,
    NULL,
    "chart",
    (void *)"WebSocket chart room"
};

static const struct lws_protocol_vhost_options pvo = {
    NULL,
    &pvo_ops,
    "wss",
    ""
};

struct lws_protocols protocols[] = {
    {
        .name = "https",
        .callback = http_cb,
        .id = 0,
        .per_session_data_size = sizeof(struct pss),
        .user = NULL,
        .rx_buffer_size = 0,
        .tx_packet_size = 0
    },
    {
        .name = "wss",
        .callback = ws_server_msg_cb,
        .per_session_data_size = sizeof(struct per_session_data),
        .user = NULL,
        .rx_buffer_size = 0,
        .tx_packet_size = 0
    },
    {
        NULL,
        0,
        0,
        0,
        0,
        NULL
    }
};

int main(int argc, const char *argv[]) {
    int logs = LLL_USER | LLL_DEBUG | LLL_WARN | LLL_NOTICE | LLL_ERR;

    const char *sport = lws_cmdline_option(argc, argv, "-p");
    const char *root = lws_cmdline_option(argc, argv, "-r");
    const char *def_page = lws_cmdline_option(argc, argv, "-d");

    struct lws_http_mount mout = {
            .mount_next = NULL,
            .mountpoint = "/",
            .origin = root,
            .def = def_page,
            .origin_protocol = LWSMPRO_FILE,
            .mountpoint_len = 1,
            .cache_revalidate = 0,
            .protocol = NULL,
            .cgienv = NULL,
            .extra_mimetypes = NULL,
            .interpret = NULL,
            .basic_auth_login_file = NULL
    };

    struct lws_context_creation_info info = {0};

    lws_set_log_level(logs, NULL);

    if (!sport)
        return -1;

    int port = strtoul(sport, NULL, 0);

    if (port <= 0 || port >= 65535)
        return -1;

    info.port = port;
    info.iface = NULL,
    info.protocols = protocols;
    info.mounts = &mout;
    info.gid = -1;
    info.uid = -1;
    info.pvo = &pvo;
    info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | LWS_SERVER_OPTION_EXPLICIT_VHOSTS ; /** LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; */
    info.ssl_cert_filepath = "localhost-100y.cert";
    info.ssl_private_key_filepath = "localhost-100y.key";
    info.vhost_name = "localhost";


    struct lws_context *ctx = lws_create_context(&info);
    if (!lws_create_vhost(ctx, &info))
    {
        lwsl_err("failed to create tls vhost\n");
        goto fail_out;
    }
    signal(SIGINT, sighook);

    while(!exit_sig)
    {
        lws_service(ctx, 1000);
    }
    fail_out:
    lws_context_destroy(ctx);

    return 0;
}
